package main

import (
	"fmt"
	"math"
	"reflect"
	"runtime"
)

func main() {
	_, desc, _ := evalOp(163, 24, "-")
	fmt.Println(desc)
	_, errDesc, err := evalOp(163, 24, "==")
	fmt.Println(errDesc, err)
	q, r := div(100, 3)
	fmt.Println(q, "---", r)

	fmt.Println(apply(pow, 3, 4))
	//匿名函数
	fmt.Println(apply(func(a int, b int) int {
		return a + b
	}, 3, 4))
	//可变参数
	fmt.Println(sum(1, 2, 3, 4, 5))

	a, b := 30, 60
	swap(&a, &b)
	fmt.Println(a, b)

}

func swap(a, b *int) {
	*b, *a = *a, *b
}

func sum(numbers ...int) int {
	sum := 0
	for _, number := range numbers {
		sum += number
	}
	return sum
}

func pow(a, b int) int {
	return int(math.Pow(float64(a), float64(b)))
}

func apply(op func(int, int) int, a, b int) int {
	p := reflect.ValueOf(op).Pointer()
	opName := runtime.FuncForPC(p).Name()
	fmt.Printf("Calling function %s with args (%d,%d) ", opName, a, b)
	return op(a, b)
}

func div(a, b int) (q, r int) {
	q = a / b
	r = a % b
	return
}

func evalOp(a, b int, op string) (result int, desc string, err error) {
	switch op {
	case "+":
		result = a + b
	case "-":
		result = a - b
	case "*":
		result = a - b
	case "/":
		result = a / b
	default:
		return 0, "", fmt.Errorf("unsupported operator:" + op)
	}
	desc = fmt.Sprintf("%d %s %d = %d", a, op, b, result)
	return
}
